/*
 * jxSwing Project (2014)
 * 
 * by Denilson Edinaldo Pinto
 * 
 * LGPL
 * Copyright (C) 2014
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package org.jxSwing.component.table.cellEditor;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyEvent;
import java.text.ParseException;
import java.util.EventObject;
import java.util.Locale;

import javax.swing.DefaultCellEditor;
import javax.swing.JFormattedTextField;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.text.MaskFormatter;

import org.jxSwing.component.spinner.DateSpinner;
import org.jxSwing.i18n.I18N;

/**
 * @author Denilson Edinaldo Pinto
 * @porject jxSwing
 * @package org.jxSwing.component.table.cellEditor
 * @date 09/02/2014 - 08:30:24
 */
public class DateSpinnerEditor extends DefaultCellEditor {
	
	private static final long serialVersionUID = 3609127873897783433L;
	
	private DateSpinner spinner;
	
	private boolean valueSet;
	
	/**
	 * 
	 */
	public DateSpinnerEditor() {
	
		this(Locale.getDefault().getCountry().equals("BR") ? "##/##/####" : "####-##-##", Locale.getDefault().getCountry().equals("BR") ? "dd/MM/yyyy" : "yyyy-MM-dd");
	}
	
	/**
	 * @param mask
	 * @param pattern
	 */
	public DateSpinnerEditor(final String mask, final String pattern) {
	
		super(new JFormattedTextField(getMaskFormatter(mask)));
		
		initGUI(pattern);
	}
	
	/**
	 * @param pattern
	 */
	private void initGUI(final String pattern) {
	
		//
		spinner = new DateSpinner(pattern);
		
		//
		spinner.getTextField().addFocusListener(new FocusAdapter() {
			
			@Override
			public void focusGained(final FocusEvent focusEvent) {
			
				//
				SwingUtilities.invokeLater(new Runnable() {
					
					@Override
					public void run() {
					
						//
						if(valueSet) {
							
							spinner.getTextField().setCaretPosition(1);
						}
					}
				});
			}
		});
		
		//
		spinner.getTextField().addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(final ActionEvent actionEvent) {
			
				stopCellEditing();
			}
		});
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.swing.DefaultCellEditor#getCellEditorValue()
	 */
	@Override
	public Object getCellEditorValue() {
	
		return spinner.getValue();
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.swing.DefaultCellEditor#getTableCellEditorComponent(javax.swing.JTable, java.lang.Object, boolean, int, int)
	 */
	@Override
	public Component getTableCellEditorComponent(final JTable table, final Object value, final boolean isSelected, final int row, final int column) {
	
		//
		if( !valueSet) {
			
			if(value != null) {
				
				spinner.setValue(value);
				
			}else {
				
				//
				if(JOptionPane.showConfirmDialog(null, I18N.component().wantToUseDateTimeNow()) != JOptionPane.YES_OPTION) {
					
					return null;
				}
			}
		}
		
		//
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
			
				spinner.getTextField().requestFocus();
			}
		});
		
		return spinner;
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.swing.DefaultCellEditor#isCellEditable(java.util.EventObject)
	 */
	@Override
	public boolean isCellEditable(final EventObject eventObject) {
	
		//
		if(eventObject instanceof KeyEvent) {
			
			final KeyEvent keyEvent = (KeyEvent)eventObject;
			
			spinner.getTextField().setText(String.valueOf(keyEvent.getKeyChar()));
			
			valueSet = true;
			
		}else {
			
			valueSet = false;
		}
		
		return true;
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.swing.DefaultCellEditor#stopCellEditing()
	 */
	@Override
	public boolean stopCellEditing() {
	
		try {
			spinner.getEditor().commitEdit();
			spinner.commitEdit();
			
		}catch(final ParseException parseException) {
			
			parseException.printStackTrace();
		}
		
		return super.stopCellEditing();
	}
	
	/**
	 * @param mask
	 * @return maskFormatter
	 */
	private static MaskFormatter getMaskFormatter(final String mask) {
	
		try {
			//
			return new MaskFormatter(mask);
			
		}catch(final ParseException parseException) {
			// ignore
		}
		
		return null;
	}
}
